package com.example.mybatisplus.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.mybatisplus.mapper.*;
import com.example.mybatisplus.model.domain.*;
import com.example.mybatisplus.model.dto.DormitoryAdminForm;
import com.example.mybatisplus.model.dto.RepairForm;
import com.example.mybatisplus.model.dto.RoomAdjustForm;
import com.example.mybatisplus.service.DormitoryAdminService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zzy
 * @since 2024-06-24
 */
@Service
public class DormitoryAdminServiceImpl extends ServiceImpl<DormitoryAdminMapper, DormitoryAdmin> implements DormitoryAdminService {

    @Autowired
    private DormitoryAdminMapper dormitoryAdminMapper;
    @Autowired
    private AdjustDormitoryMapper adjustDormitoryMapper;
    @Autowired
    private KeeperMapper keeperMapper;
    @Autowired
    private RepairMapper repairMapper;
    @Autowired
    private BuildingMapper buildingMapper;
    @Autowired
    private RoomMapper roomMapper;
    @Autowired
    private HygieneCheckMapper hygieneCheckMapper;
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private IndisciplineMapper indisciplineMapper;
    @Autowired
    private RatingTableMapper ratingTableMapper;
    public List<RoomAdjustForm> selectInroomAdjust(Dot dot) {
        List<RoomAdjustForm> roomAdjustForms = dormitoryAdminMapper.selectInroomAdjust(dot);
        return roomAdjustForms;
    }


    public List<RoomAdjustForm> selectOutroomAdjust(Dot dot) {
        List<RoomAdjustForm> roomAdjustForms = dormitoryAdminMapper.selectOutroomAdjust(dot);
        return roomAdjustForms;
    }


    public boolean confirmAdjust(Long ID,Long roomID) {
        boolean confirmed = dormitoryAdminMapper.confirmAdjust(ID,roomID);
        return confirmed;
    }


    public List<RoomAdjustForm> selectInBuildingAdjust(Dot dot) {
        List<RoomAdjustForm> roomAdjustForms = dormitoryAdminMapper.selectInBuildingAdjust(dot);
        return roomAdjustForms;
    }
    public List<RoomAdjustForm> selectAllocationInBuildingAdjust(Dot dot) {
        List<RoomAdjustForm> roomAdjustForms = dormitoryAdminMapper.selectAllocationInBuildingAdjust(dot);
        return roomAdjustForms;
    }


    public List<DormitoryAdminForm> selectDormitoryAdminByNameAndAccount(Dot dot) {
        List<DormitoryAdminForm> dormitoryAdminForms = dormitoryAdminMapper.selectDormitoryAdminFormByNameAndAccount(dot);
        return dormitoryAdminForms;
    }


    public List<DormitoryAdminForm> dormitoryAdminAll(Dot dot) {
        List<DormitoryAdminForm> dormitoryAdminForms = dormitoryAdminMapper.dormitoryAdminAll(dot);
        return dormitoryAdminForms;
    }
    public Room getOneRoom(Long id) {
        Room room = dormitoryAdminMapper.getOneRoom(id);
        return room;
    }
    public List<Keeper> getKeepers(){
        QueryWrapper<Keeper> wrapper = new QueryWrapper<>();
        wrapper.eq("is_deleted",0);
        List<Keeper> keepers =keeperMapper.selectList(wrapper);
        return keepers;
    }
    public boolean updateRepair(Long repairID, Long keeperID) {
        UpdateWrapper<Repair> wrapper = new UpdateWrapper<>();
        wrapper.eq("id",repairID);
        wrapper.set("keeper",keeperID);
        wrapper.set("state","处理中");
        wrapper.set("modified_time",LocalDateTime.now());
        UpdateWrapper<Keeper> wrapper1 = new UpdateWrapper<>();
        wrapper1.eq("id",keeperID);
        wrapper1.set("tasks",keeperMapper.selectById(keeperID).getTasks()+1);
        return (repairMapper.update(null,wrapper) + keeperMapper.update(null,wrapper1))>0;
    }
    public String getBuildingName(int id){
        QueryWrapper<DormitoryAdmin> wrapper = new QueryWrapper<>();
        wrapper.eq("ID",id);
        Long buildingID = dormitoryAdminMapper.selectOne(wrapper).getBuilding();
        QueryWrapper<Building> wrapper2 = new QueryWrapper<>();
        wrapper2.eq("ID",buildingID);
        return buildingMapper.selectOne(wrapper2).getName();
    }
    public void insertActivity(Long id, LocalDateTime checkTime){
        QueryWrapper<DormitoryAdmin> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("ID",id);
        Long buildingID = dormitoryAdminMapper.selectOne(wrapper1).getBuilding();
        QueryWrapper<Room> wrapper2 = new QueryWrapper<>();
        wrapper2.eq("building",buildingID);
        for(Room room:roomMapper.selectList(wrapper2)){
            HygieneCheck hygieneCheck = new HygieneCheck();
            hygieneCheck.setDormitoryAdmin((long) id);
            hygieneCheck.setRoom(room.getId());
            hygieneCheck.setCheckTime(checkTime);
            hygieneCheckMapper.insert(hygieneCheck);
        }
    }
    public List<HygieneCheck> getAllActivity(Dot dot) {
        List<HygieneCheck> activities = dormitoryAdminMapper.getAllActivity(dot);
        return activities;
    }
    public List<HygieneCheck> getOneActivity(Dot dot) {
        List<HygieneCheck> activities = dormitoryAdminMapper.getOneActivity(dot);
        return activities;
    }
    public boolean updateGrade(Long id, int grade){
        UpdateWrapper<HygieneCheck> wrapper = new UpdateWrapper<>();
        wrapper.eq("ID",id);
        wrapper.set("grade",grade);
        return hygieneCheckMapper.update(null,wrapper)>0;
    }
    public boolean updateGradeList(Long dormitoryAdminID, LocalDateTime checkTime, String roomName, int grade) {
        QueryWrapper<DormitoryAdmin> wrapper1 =new QueryWrapper<>();
        wrapper1.eq("ID",dormitoryAdminID);
        Long buildingID = dormitoryAdminMapper.selectOne(wrapper1).getBuilding();
        QueryWrapper<Room> wrapper2 = new QueryWrapper<>();
        wrapper2.eq("name",roomName);
        wrapper2.eq("building",buildingID);
        Long roomID = roomMapper.selectOne(wrapper2).getId();
        UpdateWrapper<HygieneCheck> wrapper3 = new UpdateWrapper<>();
        wrapper3.eq("room",roomID).eq("check_time",checkTime).eq("dormitory_admin",dormitoryAdminID);
        wrapper3.set("grade",grade);
        return hygieneCheckMapper.update(null,wrapper3)>0;
    }
    public  List<Student> getStudent(Long dormitoryAdminID) {
        QueryWrapper<DormitoryAdmin> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("ID",dormitoryAdminID);
        Long buildingID = dormitoryAdminMapper.selectOne(wrapper1).getBuilding();
        QueryWrapper<Room> wrapper2 = new QueryWrapper<>();
        wrapper2.eq("building",buildingID);
        List<Room> rooms = roomMapper.selectList(wrapper2);
        List<Student> studentList = new ArrayList<>();
        for(Room room:rooms){
            QueryWrapper<Student> wrapper3 = new QueryWrapper<>();
            wrapper3.eq("room",room.getId());
            studentList.addAll(studentMapper.selectList(wrapper3));
        }
        return studentList;
    }
    public boolean createdIndiscipline(Long dormitoryAdminID, Long studentID, String state, LocalDateTime occurrenceTime, String reason){
        Indiscipline indiscipline = new Indiscipline();
        indiscipline.setDormitoryAdmin(dormitoryAdminID);
        indiscipline.setStudent(studentID);
        indiscipline.setState(state);
        indiscipline.setOccurrenceTime(occurrenceTime);
        indiscipline.setReason(reason);
        indiscipline.setCreatedTime(LocalDateTime.now());
        indiscipline.setModifiedTime(LocalDateTime.now());
        return indisciplineMapper.insert(indiscipline)>0;
    }
    public List<Indiscipline> getIndiscipline(Dot dot){
        return dormitoryAdminMapper.getIndiscipline(dot);
    }
    public List<RoomAdjustForm> selectInAllocationAdjust(Dot dot){
        return dormitoryAdminMapper.selectInAllocationAdjust(dot);
    }
    public List<RoomAdjustForm> selectOutAllocationAdjust(Dot dot){
        return dormitoryAdminMapper.selectOutAllocationAdjust(dot);
    }
    public List<RepairForm> getDoneRepair(Dot dot){
        return dormitoryAdminMapper.selectDoneRepair(dot);
    }
    public List<Room> getRooms(Long dormitoryAdminID){
        QueryWrapper<DormitoryAdmin> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("ID",dormitoryAdminID);
        Long buildingID = dormitoryAdminMapper.selectOne(wrapper1).getBuilding();
        QueryWrapper<Room> wrapper2 = new QueryWrapper<>();
        wrapper2.eq("building",buildingID);
        return roomMapper.selectList(wrapper2);
    }
    public List<HygieneCheck> getHygieneByRoom(Dot dot) {
        return dormitoryAdminMapper.getHygieneByRoom(dot);
    }
    public  List<Indiscipline> getIndisciplineByStudent(Dot dot){
        return dormitoryAdminMapper.getIndisciplineByStudent(dot);
    }
    public boolean updateRating(Long dormitoryAdminID){
        QueryWrapper<DormitoryAdmin> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("ID",dormitoryAdminID);
        Long buildingID = dormitoryAdminMapper.selectOne(wrapper1).getBuilding();
        QueryWrapper<Room> wrapper2 = new QueryWrapper<>();
        wrapper2.eq("building",buildingID);
        List<Room> rooms = roomMapper.selectList(wrapper2);
        //判断是否在一周之内操作过
        for(Room room:rooms){
            QueryWrapper<RatingTable> wrapper3 = new QueryWrapper<>();
            wrapper3.eq("room",room.getId());
            List<RatingTable> ratingTables = ratingTableMapper.selectList(wrapper3);
            for(RatingTable ratingTable:ratingTables){
                LocalDateTime ratingTime = ratingTable.getRatingTime();
                LocalDateTime currentTime = LocalDateTime.now();
                LocalDate ratingDate = ratingTime.toLocalDate();
                LocalDate currentDate = currentTime.toLocalDate();
                long daysBetween = ChronoUnit.DAYS.between(ratingDate, currentDate);
                boolean isWithinOneWeek = Math.abs(daysBetween) <= 7;
                if(isWithinOneWeek){
                    return false;
                }
            }
        }
        List<RatingTable> lastRating = new ArrayList<>();
        List<HygieneCheck> HygienePoints = new ArrayList<>();
        //获取上次评比等级
        for(Room room:rooms){
            QueryWrapper<RatingTable> wrapper3 = new QueryWrapper<>();
            wrapper3.eq("room",room.getId());
            wrapper3.orderByDesc("rating_time");
            wrapper3.last("limit 1");
            lastRating.add(ratingTableMapper.selectOne(wrapper3));
        }
        //获取卫生分数
        for(Room room:rooms){
            boolean isFirst = true;
            LocalDate currentDate = LocalDate.now();
            LocalDate oneWeekAgo = currentDate.minus(7, ChronoUnit.DAYS);
            QueryWrapper<HygieneCheck> wrapper4 = new QueryWrapper<>();
            wrapper4.eq("room", room.getId());
            wrapper4.between("check_time", oneWeekAgo.atStartOfDay(), currentDate.atStartOfDay().plusDays(1));
            List<HygieneCheck> recentChecks = hygieneCheckMapper.selectList(wrapper4);
            for(HygieneCheck hygieneCheck:recentChecks){
                if(HygienePoints.isEmpty()){
                    HygienePoints.add(hygieneCheck);
                }else{
                    for(HygieneCheck hygieneCheck1:HygienePoints){
                        if(hygieneCheck.getRoom().equals(hygieneCheck1.getRoom())){
                            hygieneCheck1.setGrade(hygieneCheck1.getGrade()+hygieneCheck.getGrade());
                            isFirst=false;
                        }
                    }
                    if(isFirst){
                        HygienePoints.add(hygieneCheck);
                    }
                }
            }
        }
        //根据违纪所在寝室扣分
        QueryWrapper<Indiscipline> wrapper5 = new QueryWrapper<>();
        wrapper5.eq("dormitory_admin",dormitoryAdminID);
        List<Indiscipline> indisciplines = indisciplineMapper.selectList(wrapper5);
        for(Indiscipline indiscipline:indisciplines){
            if(indiscipline.getState().equals("已完成")){
                QueryWrapper<Student> student = new QueryWrapper<>();
                student.eq("ID",indiscipline.getStudent());
                Long roomId = studentMapper.selectOne(student).getRoom();
                for(HygieneCheck hygieneCheck:HygienePoints){
                    if(hygieneCheck.getRoom().equals(roomId)){
                        hygieneCheck.setGrade(hygieneCheck.getGrade()-indiscipline.getGrade());
                    }
                }
            }
        }
        HygienePoints.sort(Comparator.comparing(HygieneCheck::getGrade).reversed());
        for(int i=0;i<HygienePoints.size() / 2; i+=1){
            for(RatingTable r: lastRating){
                if(HygienePoints.get(i).getRoom().equals(r.getRoom())){
                    RatingTable ratingTable = new RatingTable();
                    ratingTable.setRoom(HygienePoints.get(i).getRoom()).setGrade(r.getGrade()+1).setRatingTime(LocalDateTime.now()).setIsDeleted(0);
                    ratingTableMapper.insert(ratingTable);
                }
            }
        }
        return true;
    }
    public List<RatingTable> getRating(Dot dot){
        return dormitoryAdminMapper.getRating(dot);
    }
}
